package cam.School.Services;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;

import cam.School.DAOException.DAOException;
import cam.School.DataAccessObject.ClassRoomDAO;
import cam.School.DataAccessObject.DAOFactory;
import cam.School.DataAccessObject.EmployeeDAO;
import cam.School.DataAccessObject.ImageDAO;
import cam.School.DataAccessObject.InfrastructurCategoryDAO;
import cam.School.DataAccessObject.InfrastructurDAO;
import cam.School.DataTransfertObject.CallResult;
import cam.School.DataTransfertObject.ClassRoomDTO;
import cam.School.DataTransfertObject.EmployeeDTO;
import cam.School.DataTransfertObject.InfrastructurCategoryDTO;
import cam.School.DataTransfertObject.InfrastructurDTO;
import cam.School.DataTransfertObject.MaterialDTO;

@Path("/infrastructureService")
public class InfrastructureService {
	
//	ServiceMethods:
//	 -getAllInfrastructur
//	 -getInfrastructurById
//	 -getInfrastructurByName
//	 -getInfrastructurByCategory
//	 -getInfrastructurByState //new old..
//	 -insertInfrastructur
//   -updateInfrastructur
//   -deleteInfrastructur

	
	@GET
	@Path("/getAllInfrastructuresGroupByCategory")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllInfrastructuresGroupByCategory() throws SQLException {		
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		
		InfrastructurCategoryDAO infrastructurCategoryDAO = javabase.getInfrastructurCategoryDAO();
		List<InfrastructurCategoryDTO> infrastructurCategory =  infrastructurCategoryDAO.getAllCategory();
		
		if(infrastructurCategory != null){
			
			InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();
			List<InfrastructurDTO> infrastructures =  infrastructurDAO.getAllInfrastructur();			
			
			for(int i = 0; i< infrastructurCategory.size(); i++){
				InfrastructurCategoryDTO currentInfratructurCategory = infrastructurCategory.get(i);
				for(int j = 0; j < infrastructures.size(); j++){
					if(currentInfratructurCategory.getId() == infrastructures.get(j).getCategoryId()){
						infrastructurCategory.get(i).getInfrastructures().add(infrastructures.get(j));
					}
				}			
			}
			
			ClassRoomDAO classRoomDAO = javabase.getClassRoomDAO();
			List<ClassRoomDTO> classRooms =  classRoomDAO.getAll();
			
			for(int i = 0; i < infrastructurCategory.size(); i++){
				InfrastructurCategoryDTO currentInfratructurCategory = infrastructurCategory.get(i);
				for(int j = 0; j < classRooms.size(); j++){
					if(currentInfratructurCategory.getId() == classRooms.get(j).getCategoryId()){
						infrastructurCategory.get(i).getClassRooms().add(classRooms.get(j));
					}
				}			
			}			
		}	
		
		return Response.status(Response.Status.OK).entity(infrastructurCategory).build();		
	}
	
	@GET
	@Path("/getAllInfrastructures")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllInfrastructures() throws SQLException {		
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();
		List<InfrastructurDTO> infrastructures =  infrastructurDAO.getAllInfrastructur();
		return Response.status(Response.Status.OK).entity(infrastructures).build();		
	}
	
	@GET
	@Path("/getAllMaterials")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAllMaterials() throws SQLException {		
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();
		List<MaterialDTO> materials =  infrastructurDAO.getAllMaterial();
		return Response.status(Response.Status.OK).entity(materials).build();		
	}
	
	@GET
	@Path("/getInfrastructurById/{InfrastructurId}")
	@Produces(MediaType.APPLICATION_JSON)
	public InfrastructurDTO getInfrastructurById(@PathParam("InfrastructurId") int InfrastructurId ) {		
		return null;		
	}
	
	@GET
	@Path("/getInfrastructurByName/{InfrastructurName}")
	@Produces(MediaType.APPLICATION_JSON)
	public InfrastructurDTO getInfrastructurByName(@PathParam("InfrastructurName") String InfrastructurName ) {		
		return null;		
	}
		
	@GET
	@Path("/getInfrastructurByCategory")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getInfrastructurByCategory(@QueryParam("infrastructurCategoryId") long infrastructurCategoryId ) {		
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();		
		return Response.ok((ArrayList<InfrastructurDTO>) infrastructurDAO.getByInfrastructurByCategory(infrastructurCategoryId)).build();			
	}
	
	@GET
	@Path("/getMaterialByCategory")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getMaterialByCategory(@QueryParam("materialCategoryId") long materialCategoryId ) {		
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();		
		return Response.ok((ArrayList<MaterialDTO>) infrastructurDAO.getByMaterialByCategory(materialCategoryId)).build();		
	}
	
	@GET
	@Path("/getInfrastructureCategory")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getInfrastructureCategory(@QueryParam("materialCategoryId") long materialCategoryId ) {		
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();		
		return Response.ok((ArrayList<MaterialDTO>) infrastructurDAO.getByMaterialByCategory(materialCategoryId)).build();		
	}
	
	@GET
	@Path("/getInfrastructureCategoryByName")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getInfrastructureCategoryByName(@QueryParam("categoryName") String categoryName ) {		
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurCategoryDAO infrastructurCategoryDAO = javabase.getInfrastructurCategoryDAO();		
		return Response.ok(infrastructurCategoryDAO.getCategoryByName(categoryName)).build();		
	}
	
	@POST
	@Path("/createInfrastructur")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	public Response createInfrastructur(@FormDataParam("file") InputStream uploadedInputStream,
			@FormDataParam("file") FormDataContentDisposition fileDetail, 
			@FormDataParam("infrastructurCategoryId") long infrastructurCategoryId,
			@FormDataParam("name") String name,
			@FormDataParam("description") String description,
			@FormDataParam("numberOfSits") String numberOfSits,
			@FormDataParam("personInCharge") String personInCharge,
			@FormDataParam("state") String state) throws IllegalArgumentException, DAOException, IOException {
				
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();
		
		InfrastructurDTO infrastructure = new InfrastructurDTO();
		infrastructure.setCategoryId(infrastructurCategoryId);
		infrastructure.setName(name);
		infrastructure.setDescription(description);
		infrastructure.setNumberOfSits(Integer.parseInt(numberOfSits));
		infrastructure.setFirstRegistration(new Date());
		infrastructure.setLastUpdate(new Date());
		infrastructure.setPersonInCharge(personInCharge);
		infrastructure.setState(state);
				
		CallResult infrastructurCreateResult = infrastructurDAO.createInfrastructur(infrastructure);
		
		long infrastructurId = infrastructurCreateResult.getResultCode();
		
		if((new Integer((int)infrastructurId).equals(new Integer(406))) == false){			
			if(fileDetail.getFileName()!=""){
				String fileServerLocation = "C:\\Users\\Claude\\Desktop\\CamSchool\\FileServer\\";
				String uploadedFileLocation = fileServerLocation + fileDetail.getFileName();
				 			
				// save it			
				writeToFile(uploadedInputStream, uploadedFileLocation);
				
				// save picture path on the database
				ImageDAO imageDAO = javabase.getPictureDAO();
				imageDAO.upload(infrastructurId, uploadedFileLocation);
			}			
			return Response.status(Response.Status.OK).entity(infrastructurId).build();			
		}
		
		return Response.status(Response.Status.UNAUTHORIZED).entity(infrastructurId).build();	
	}
	
	@POST
	@Path("/createMaterial")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	public Response createMaterial(@FormDataParam("file") InputStream uploadedInputStream,
			@FormDataParam("file") FormDataContentDisposition fileDetail, 
			@FormDataParam("name") String name,
			@FormDataParam("description") String description,
			@FormDataParam("categoryId") long categoryId,
			@FormDataParam("personInCharge") String personInCharge,
			@FormDataParam("state") String state) {
				
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();
		
		MaterialDTO material = new MaterialDTO();
		material.setName(name);
		material.setDescription(description);
		
		material.setFirstRegistration(new Date());
		material.setLastUpdate(new Date());
		material.setCategoryId(categoryId);
		material.setPersonInCharge(personInCharge);
		material.setState(state);
				
		CallResult materialCreateResult = infrastructurDAO.createMaterial(material);
		
		long materialId = materialCreateResult.getResultCode();
		
		if((new Integer((int)materialId).equals(new Integer(406))) == false){
			
			if(fileDetail.getFileName()!=""){
				String fileServerLocation = "C:\\Users\\Claude\\Desktop\\CamSchool\\FileServer\\";
				String uploadedFileLocation = fileServerLocation + fileDetail.getFileName();
				 			
				// save it			
				writeToFile(uploadedInputStream, uploadedFileLocation);
			}	
			
			return Response.status(Response.Status.OK).entity(materialId).build();			
		}
		
		return Response.status(Response.Status.UNAUTHORIZED).entity(materialId).build();	
	}
	
	// save uploaded file to new location
	private void writeToFile(InputStream uploadedInputStream,
		String uploadedFileLocation) {
 
		try {
			OutputStream out = new FileOutputStream(new File(
					uploadedFileLocation));
			int read = 0;
			byte[] bytes = new byte[1024];
 
			out = new FileOutputStream(new File(uploadedFileLocation));
			while ((read = uploadedInputStream.read(bytes)) != -1) {
				out.write(bytes, 0, read);
			}
			out.flush();
			out.close();
		} catch (IOException e) { 
			e.printStackTrace();
		} 
	}
	
	@POST
	@Path("/updateInfrastructur/{infrastructurData}")
	@Produces(MediaType.TEXT_XML)
	public boolean updateInfrastructur(@PathParam("infrastructurId") String infrastructurData ) {				  
		//search by infrastructurId
//		InfrastructurData ={
//				  "FirstName":"NewFirstName",
//				  "LastName":"NewLastName",
//				  "StreetNr":"NewStreetNr",
//				  "City":"NewCity",
//				  "ZipCode":"90567",
//				  "Country":"NewCountry",
//				  "Birthday":"10.10.1984",
//				  "Email":"newEmail@yahoo.de",
//				  "CellPhone":"00237998764526",
//				  "WorkPhone":"0023733457635",
//				  "IsPrincipalTeacher":"true",
//				  "Deleted:"false",
//				  "FirstRegistration:"10.11.2014",
//				  "LastUpdate:"10.11.2014",
//				  "MatriculationNumber:"NewMatriculationNumber",
//				  "PictureId":"234",
//				  "Profession:"English Teacher"
//		}
		return true; // or false falls es nicht gespeichert werden kann.		
	}	
		
	@GET
	@Path("/deleteInfrastructur")
	@Produces(MediaType.APPLICATION_JSON)
	public Response deleteInfrastructur(@QueryParam("infrastructurId") long infrastructurId ) throws Exception {				  
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();		
		return Response.ok(infrastructurDAO.deleteInfrastructur(infrastructurId)).build();			
	}
	
	@GET
	@Path("/deleteMaterial")
	@Produces(MediaType.APPLICATION_JSON)
	public Response deleteMaterial(@QueryParam("materialId") long materialId ) throws Exception {				  
		DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
		InfrastructurDAO infrastructurDAO = javabase.getInfrastructurDAO();		
		return Response.ok(infrastructurDAO.deleteMaterial(materialId)).build();			
	}
}
